package matsk.mszdqabbs.IO;

import matsk.mszdqabbs.Configuration.conf.imageResourceMapper;
import matsk.mszdqabbs.Utils.PictureUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Objects;

@Component
public class ContentImageIO {
    //最大允许的上传图片大小
    private static final long maxAllowedSize = 1048576L;//1MB

    /**
     * 存储图片文件到本地硬盘
     * 如果失败会返回“写入失败”
     * 成功的话会返回写入本地的新文件名
     * @param file 用户上传的图片
     * @return 文件名或失败信息
     */
    public String saveImageFile(MultipartFile file) {
        int dotIndex = Objects.requireNonNull(file.getOriginalFilename()).lastIndexOf(".");
        File newImage = null;
        if(dotIndex != -1) {
            String autoGeneratedFilename = generateFilename(
                    file.getOriginalFilename().substring(dotIndex));

            newImage = new File(imageResourceMapper.getContentPhotoFileLocationByEnvironment() + autoGeneratedFilename);
            //第一次创建需要生成目录
            if(!newImage.exists()) {
                if(!newImage.mkdirs()) {
                    return "写入失败";
                }
            }
            try {
                file.transferTo(newImage);
                //若用户上传的图片过大，则需要进行压缩处理
                if(newImage.length() > maxAllowedSize) {
                    //重新生成一个新的图片文件名称，标识压缩后的图片
                    autoGeneratedFilename = generateFilename(
                            file.getOriginalFilename().substring(dotIndex));
                    //创建压缩图片文件
                    File lowQualityImage = new File(imageResourceMapper.getContentPhotoFileLocationByEnvironment()
                            + autoGeneratedFilename);
                    //压缩至500KB左右
                    PictureUtils.lowQuality(
                            imageResourceMapper.getContentPhotoFileLocationByEnvironment() + newImage.getName()
                    ,imageResourceMapper.getContentPhotoFileLocationByEnvironment() + lowQualityImage.getName(),
                            1024);
                    //删除未压缩的图片文件
                    if(!newImage.delete()) return "写入失败";
                    //替换压缩后的图片文件
                    newImage = lowQualityImage;
                }
            } catch (IOException e) {
                e.printStackTrace();
                return "写入失败";
            }
        }
        return newImage == null ? "写入失败" : newImage.getName();
    }

    /**
     * 通过系统当前时间戳和产生0 - 99随机数命名新文件
     * 确保文件名的唯一性
     * @param suffix 文件后缀
     * @return 随机生成的名字
     */
    private synchronized String generateFilename(String suffix) {
        return System.currentTimeMillis() + "" + (int)(Math.random() * 100) + suffix;
    }
}
